Githook实践以代码规范检测插件golangci | 您所在的位置:网站首页 › golangci-lint 插件 › Githook实践以代码规范检测插件golangci |
「这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战」 引子"kovogo哥, 我怎么提交不了代码了" 没想到工作两年就已经进入哥字辈了, 往旁边一看旁边新来的小伙子正常对着屏幕发愁, 一看控制台的报错,哦原来是golangci-lint打回了提交, 原因是某一行的代码太长了超过了限制。 那么在提交代码对代码规范进行检查是怎么做到的? 这就需要我们来回顾一下githook的知识了。 githook什么是githook? 一般来说只要是上了规模的软件/中间件/开源框架或多或少的会提供一些hook, 供开发人员使用。而这些hook的作用就是在这些框架/软件中引入开发人员编写代码, 从而改变软件的表现形式或行为逻辑。 而githook就是git是向开发者提供的在git执行重要的操作引入开发者的代码的功能,比如上文提到在commit时引入代码检查的功能就是通过githook实现的。 每个git仓库在初始化的时候, 都会在.git目录下创建一个hooks目录,用来存放开发人员自定义的hook脚本(shell脚本), 脚本文件名即hook名。 windows 环境安装git时会自带git bash, 因此无需要担心脚本的兼容性 当hook脚本返回0时表示放行对应的操作, 返回非0值表示拒绝此操作。 每个程序在退出的时候都会有返回值, 该返回值通常用来表示程序是否执行成功. 在Linux shell中我们可以通过, $?来获取上一个程序的返回值. 如上图所示, 我们尝试访问一个不存在的路径, ls命令的返回值是2. 我们可以在.git/hooks中看到如下文件: 上图中.sample文件都是git官方提供的参考, 去掉.sample后缀该钩子就会起效, 记住: 文件名即钩子名 如果需要在提交代码时对代码进行检测,我们就需要为pre-commit钩子编写代码规范检测脚本。 更多详细信息可参见官方文档 golintci-lint由于golint已经被谷歌抛弃不再维护了, 我们使用了golangci-lint对代码规范进行检查。 安装golangci-lint官网给出的安装方式有两种: 二进制安装, 直接下载对应平台的可执行文件 如果版本小于1.16使用go get下载源文件并编译安装, 大于1.16则使用go install # Go 1.16+ go install github.com/golangci/golangci-lint/cmd/[email protected] # Go version < 1.16 go get -u github.com/golangci/golangci-lint/cmd/[email protected] 复制代码以windows平台为例, 我的golang版本是1.16.10 因此我们使用go install的方式进行安装 使用run命令即可对目标目录的代码进行检测 golangci-lint run [目录] 复制代码使用-h可以查看run命令的更多帮助信息 golangci-lint run -h 复制代码值得注意的选项有: --issues-exit-code 代码检测失败返回的错误码, 默认是1 -c, --config PATH 用于定制代码检测项目的配置文件(yaml格式) --skip-files 要跳过的文件 --skip-dirs 要跳过的目录 --enable 要启用的代码检测项目 定制代码检测上文提到, 我们可以通过--config来定制代码检测项目的配置, 其格式如下: linters-settings: cyclop: # 代码检测项目名通常会对应到某个插件 # 最大的复杂度 max-complexity: 10 # 每个包允许的最大复杂度 package-average: 0.0 # 是否跳过测试文件 skip-tests: false 复制代码更多信息参考官方文档 githook + golangci-lint以windows平台为例, 我们新建一个项目 然后新建一个代码文件, 随便写点乱七八糟的代码: func main() { for i := 0; i < 1024; i++ { for j := 0; j < 1024; j++ { for n := 0; n < 1024; n++ { fmt.Printf("%d-%d-%s", i, j, n) } } } } 复制代码golangci-lint检测到了Printf传了错误的参数 我们再往项目中里面加点有"坏味道"的代码, 如下所示:(示例来自cyclop项目的测试文件) func T() { i := 1 if i > 2 { if i > 2 { } if i > 2 { } if i > 2 { } if i > 2 { } } else { if i > 2 { } if i > 2 { } if i > 2 { } if i > 2 { } } if i > 2 { } } 复制代码再次进行代码检测, 注意此时需要启用圈复杂度检测插件cyclop 如果我们想要让代码通过检测,就需要使用到上文提到的使用配置文件自定义代码检测项目了。 在项目中创建lint.yaml, 并编写配置项如下 linters-settings: cyclop: # 最大的复杂度 max-complexity: 15 # 每个包允许的最大复杂度 package-average: 0.0 # 是否跳过测试文件 skip-tests: false 复制代码再次运行并指定配置文件, 此时已不再提示圈复杂度过高 利用上文的知识,我们的pre-commit hook 脚本的逻辑如下所示: 检测是否安装golangci-lint, 如果没有则进行安装 运行golangci-lint对代码进行检测,如果检测失败返回1成功则返回0 #!/bin/sh echo "Start lint code" if !(golangci-lint.exe --version); then go install github.com/golangci/golangci-lint/cmd/[email protected] fi # 目录名后跟上...表示对该目录进行递归查找 if !(golangci-lint.exe run --enable cyclop --config ./lint.yaml ./...); then echo "Lint fail!" exit 1 fi echo "Lint success" exit 0 复制代码尝试对代码提交,运行效果如下图所示 |
CopyRight 2018-2019 实验室设备网 版权所有 |